<?php

/**
 * 购物车模块
 * @author Samuel
 * @since 2012.5.5
 */
class Shopping_Model {

    protected $uId;
    /**
     * 购物车内的商品数据
     * @var array(
     *      shoppingList:array(
     *          productId=>num
     *      )
     * )
     */
    protected $_data;
    /**
     * 缓存的KEY
     */
    protected $_cacheKey;
    /**
     * 缓存实例
     *
     * @var Helper_Redis
     */
    protected $_cacheInstance;

    /**
     * 缓存的命名空间
     */
    const CACHE_NS = '_shopping';

    /**
     * 单例对象
     */
    public static $singletonObjects = array();

    /**
     * 获取单例
     * @param $uId 用户ID
     * @return Shopping_Model
     * @throws AppException
     */
    public static function getInstance($uId) {
        $className = __CLASS__;
        if (!isset(self::$singletonObjects[$uId][$className])) {
            self::$singletonObjects[$uId][$className] = new self($uId);
        }

        return self::$singletonObjects[$uId][$className];
    }

    /**
     * 构造函数
     * @param int $uId
     */
    public function __construct($uId) {
        $this->_cacheKey = $uId . self::CACHE_NS;
        $this->_cacheInstance = $this->_getCache();
        $shoping = array('shoppingList' => $this->_cacheInstance->hgetall($this->_cacheKey));
        $this->_data = $shoping;
        print_r($this->_data);
        if ($this->_data === false) {
            
        }
    }

    public function getShoppingList() {
        return $this->_data['shoppingList'];
    }

    /**
     * 添加购物记录
     * @param int $productId    商品id
     * @param int $num          商品数量
     * @return array            购物记录列表
     * @throws AppException     303：model层参数错误 
     */
    public function increaseShopping($productId, $num) {
        //参数验证
        if ($productId <= 0 || $num <= 0) {
            throw new AppException(303);
        }
print_r($this->_cacheInstance->hgetall($this->_cacheKey));
//        $this->_cacheInstance->flushDB();//清空数据库
        //不存在购物车记录则创建记录
        if (!isset($this->_data['shoppingList'][$productId])) {
            $this->_data['shoppingList'][$productId] = $num;
        }
        //存在购物车记录则增加
        else {
            $this->_data['shoppingList'][$productId] += $num;
        }
        
        //写入redis
        $this->_saveToCache();
        print_r($this->_cacheInstance->hgetall($this->_cacheKey));
        return $this->_data['shoppingList'];
    }

    /**
     * 减少购物车记录
     * @param int $productId    商品Id
     * @param int $num          商品数量
     * @return array            购物记录列表
     * @throws AppException     303，8000
     */
    public function decreaseShopping($productId, $num) {
        //参数验证
        if ($productId <= 0 || $num <= 0) {
            throw new AppException(303);
        }

        //验证是否存在购物车记录
        if (!isset($this->_data['shoppingList'][$productId])) {
            throw new AppException(8000);
        }

        //计算商品数量
        $productNum = $this->_data['shoppingList'][$productId] - $num;

        //商品数量大于0，赋值
        if ($productNum > 0) {
            $this->_data['shoppingList'][$productId] = $productNum;
        }
        //商品数量小于或等于0，释放
        else {
            unset($this->_data['shoppingList'][$productId]);
        }
        $this->_saveToCache();

        return $this->_data['shoppingList'];
    }

    /**
     * 清空购物车
     * @return type 
     */
    public function cleanShopping() {
        if (!empty($this->_data['shoppingList'])) {
            unset($this->_data['shoppingList']);
        }
        $this->_saveToCache();

        return array();
    }

    /**
     * @return Helper_Redis
     */
    protected function _getCache() {
//        return Helper_Redis::getInstance( 'etc' );
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6380);
        return $redis;
    }

    /**
     * 将数据保存到缓存
     */
    protected function _saveToCache() {
        if (is_array($this->_data)) {
            foreach ($this->_data['shoppingList'] as $key => $value) {
                $this->_cacheInstance->hSet($this->_cacheKey, $key, $value);
            }
        }
    }

}